﻿package morn.core.components
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import morn.core.handlers.*;

    public class ScrollBar extends Component implements ISkinAbleContainer
    {
        protected var _scrollSize:Number = 1;
        protected var _skin:String;
        protected var _upButton:Button;
        protected var _downButton:Button;
        protected var _slider:Slider;
        protected var _changeHandler:Handler;
        protected var _thumbPercent:Number = 1;
        protected var _target:Component;
        protected var _touchScrollEnable:Boolean;
        protected var _lastPoint:Point;
        protected var _lastOffset:Number;
        protected var _scrollStep:int = 5;
        private var _skinChanged:Boolean = false;
        public static const HORIZONTAL:String = "horizontal";
        public static const VERTICAL:String = "vertical";

        public function ScrollBar(param1:String = null) : void
        {
            this._touchScrollEnable = MornConfig.touchScrollEnable;
            if (param1 != null)
            {
                this.skin = param1;
            }
            return;
        }// end function

        public function set scrollStep(param1:int) : void
        {
            this._scrollStep = param1;
            return;
        }// end function

        public function setSkin(param1:Object) : void
        {
            if (!this._skinChanged)
            {
                if (this._skin != String(this.value))
                {
                    this._skin = param1 as String;
                    this._slider.setSkin(this._skin);
                    this._upButton.skin = this._skin + "$up";
                    this._downButton.skin = this._skin + "$down";
                    this.changeScrollBar();
                }
                this._skinChanged = true;
            }
            this.changeSize();
            return;
        }// end function

        public function set skinChanged(param1:Boolean) : void
        {
            this._skinChanged = param1;
            return;
        }// end function

        override protected function preinitialize() : void
        {
            mouseChildren = true;
            return;
        }// end function

        override protected function createChildren() : void
        {
            var _loc_1:* = new Slider();
            this._slider = new Slider();
            addChild(_loc_1);
            var _loc_1:* = new Button();
            this._upButton = new Button();
            addChild(_loc_1);
            var _loc_1:* = new Button();
            this._downButton = new Button();
            addChild(_loc_1);
            return;
        }// end function

        override protected function initialize() : void
        {
            this._slider.showLabel = false;
            this._slider.addEventListener(Event.CHANGE, this.onSliderChange);
            this._slider.setSlider(0, 0, 0);
            this._upButton.addEventListener(MouseEvent.MOUSE_DOWN, this.onButtonMouseDown);
            this._downButton.addEventListener(MouseEvent.MOUSE_DOWN, this.onButtonMouseDown);
            return;
        }// end function

        protected function onSliderChange(event:Event) : void
        {
            sendEvent(Event.CHANGE);
            if (this._changeHandler != null)
            {
                this._changeHandler.executeWith([this.value]);
            }
            return;
        }// end function

        protected function onButtonMouseDown(event:MouseEvent) : void
        {
            var _loc_2:* = event.currentTarget == this._upButton;
            this.slide(_loc_2);
            App.timer.doOnce(Styles.scrollBarDelayTime, this.startLoop, [_loc_2]);
            App.stage.addEventListener(MouseEvent.MOUSE_UP, this.onStageMouseUp);
            return;
        }// end function

        protected function startLoop(param1:Boolean) : void
        {
            App.timer.doFrameLoop(1, this.slide, [param1]);
            return;
        }// end function

        protected function slide(param1:Boolean) : void
        {
            if (param1)
            {
                this.value = this.value - this._scrollSize;
            }
            else
            {
                this.value = this.value + this._scrollSize;
            }
            return;
        }// end function

        protected function onStageMouseUp(event:MouseEvent) : void
        {
            App.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onStageMouseUp);
            App.timer.clearTimer(this.startLoop);
            App.timer.clearTimer(this.slide);
            return;
        }// end function

        public function get skin() : String
        {
            return this._skin;
        }// end function

        public function set skin(param1:String) : void
        {
            if (this._skin != param1)
            {
                this._skin = param1;
                this._slider.skin = this._skin;
                this._upButton.skin = this._skin + "$up";
                this._downButton.skin = this._skin + "$down";
                this.changeScrollBar();
            }
            this._skinChanged = true;
            return;
        }// end function

        protected function changeScrollBar() : void
        {
            if (this._slider.direction == VERTICAL)
            {
                this._slider.y = this._upButton.height;
            }
            else
            {
                this._slider.x = this._upButton.width;
            }
            this.resetButtonPosition();
            return;
        }// end function

        protected function resetButtonPosition() : void
        {
            if (this._slider.direction == VERTICAL)
            {
                this._downButton.y = this._slider.y + this._slider.height;
                _contentWidth = this._downButton.width;
                _contentHeight = this._downButton.y + this._downButton.height;
            }
            else
            {
                this._downButton.x = this._slider.x + this._slider.width;
                _contentWidth = this._downButton.x + this._downButton.width;
                _contentHeight = this._downButton.height;
            }
            return;
        }// end function

        override protected function changeSize() : void
        {
            super.changeSize();
            if (this._slider.direction == VERTICAL)
            {
                this._slider.height = height - this._upButton.height - this._downButton.height;
            }
            else
            {
                this._slider.width = width - this._upButton.width - this._downButton.width;
            }
            this.resetButtonPosition();
            return;
        }// end function

        public function setScroll(param1:Number, param2:Number, param3:Number) : void
        {
            exeCallLater(this.changeSize);
            this._slider.setSlider(param1, param2, param3);
            this._upButton.disabled = param2 <= 0;
            this._downButton.disabled = param2 <= 0;
            this._slider.bar.visible = param2 > 0;
            return;
        }// end function

        public function get max() : Number
        {
            return this._slider.max;
        }// end function

        public function set max(param1:Number) : void
        {
            this._slider.max = param1;
            return;
        }// end function

        public function get min() : Number
        {
            return this._slider.min;
        }// end function

        public function set min(param1:Number) : void
        {
            this._slider.min = param1;
            return;
        }// end function

        public function get value() : Number
        {
            return this._slider.value;
        }// end function

        public function set value(param1:Number) : void
        {
            this._slider.value = param1;
            return;
        }// end function

        public function get direction() : String
        {
            return this._slider.direction;
        }// end function

        public function set direction(param1:String) : void
        {
            this._slider.direction = param1;
            return;
        }// end function

        public function get sizeGrid() : String
        {
            return this._slider.sizeGrid;
        }// end function

        public function set sizeGrid(param1:String) : void
        {
            this._slider.sizeGrid = param1;
            return;
        }// end function

        public function get scrollSize() : Number
        {
            return this._scrollSize;
        }// end function

        public function set scrollSize(param1:Number) : void
        {
            this._scrollSize = param1;
            return;
        }// end function

        override public function set dataSource(param1:Object) : void
        {
            _dataSource = param1;
            if (param1 is Number || param1 is String)
            {
                this.value = Number(param1);
            }
            else
            {
                super.dataSource = param1;
            }
            return;
        }// end function

        public function get thumbPercent() : Number
        {
            return this._thumbPercent;
        }// end function

        public function set thumbPercent(param1:Number) : void
        {
            exeCallLater(this.changeSize);
            this._thumbPercent = param1;
            if (this._slider.direction == VERTICAL)
            {
                this._slider.bar.height = Math.max(int(this._slider.height * param1), Styles.scrollBarMinNum);
            }
            else
            {
                this._slider.bar.width = Math.max(int(this._slider.width * param1), Styles.scrollBarMinNum);
            }
            return;
        }// end function

        public function get target() : Component
        {
            return this._target;
        }// end function

        public function set target(param1:Component) : void
        {
            if (this._target)
            {
                this._target.removeEventListener(MouseEvent.MOUSE_WHEEL, this.onMouseWheel);
                this._target.removeEventListener(MouseEvent.MOUSE_DOWN, this.onTargetMouseDown);
            }
            this._target = param1;
            if (param1)
            {
                this._target.addEventListener(MouseEvent.MOUSE_WHEEL, this.onMouseWheel);
                if (this._touchScrollEnable)
                {
                    this._target.addEventListener(MouseEvent.MOUSE_DOWN, this.onTargetMouseDown);
                }
            }
            return;
        }// end function

        public function get touchScrollEnable() : Boolean
        {
            return this._touchScrollEnable;
        }// end function

        public function set touchScrollEnable(param1:Boolean) : void
        {
            this._touchScrollEnable = param1;
            return;
        }// end function

        protected function onTargetMouseDown(event:MouseEvent) : void
        {
            this._target.mouseChildren = true;
            App.timer.clearTimer(this.tweenMove);
            if (!this.contains(event.target as DisplayObject))
            {
                App.stage.addEventListener(MouseEvent.MOUSE_UP, this.onStageMouseUp2);
                App.stage.addEventListener(Event.ENTER_FRAME, this.onStageEnterFrame);
                this._lastPoint = new Point(App.stage.mouseX, App.stage.mouseY);
            }
            return;
        }// end function

        protected function onStageEnterFrame(event:Event) : void
        {
            this._lastOffset = this._slider.direction == VERTICAL ? (App.stage.mouseY - this._lastPoint.y) : (App.stage.mouseX - this._lastPoint.x);
            if (Math.abs(this._lastOffset) >= 1)
            {
                this._lastPoint.x = App.stage.mouseX;
                this._lastPoint.y = App.stage.mouseY;
                this._target.mouseChildren = false;
                this.value = this.value - this._lastOffset;
            }
            return;
        }// end function

        protected function onStageMouseUp2(event:MouseEvent) : void
        {
            App.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onStageMouseUp2);
            App.stage.removeEventListener(Event.ENTER_FRAME, this.onStageEnterFrame);
            if (Math.abs(this._lastOffset) > 50)
            {
                this._lastOffset = 50 * (this._lastOffset > 0 ? (1) : (-1));
            }
            App.timer.doFrameLoop(1, this.tweenMove);
            return;
        }// end function

        private function tweenMove() : void
        {
            this._lastOffset = this._lastOffset * 0.92;
            this.value = this.value - this._lastOffset;
            if (Math.abs(this._lastOffset) < 0.5)
            {
                this._target.mouseChildren = true;
                App.timer.clearTimer(this.tweenMove);
            }
            return;
        }// end function

        protected function onMouseWheel(event:MouseEvent) : void
        {
            this.value = this.value - event.delta * this._scrollStep;
            if (this.value < this.max && this.value > this.min)
            {
                event.stopPropagation();
            }
            return;
        }// end function

    }
}
